#pragma once
#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cassert>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "Log.hpp"

using namespace std; //不推荐

//定义ftok函数的第一个参数，路径名称
#define PATH_NAME "./"
//定义ftok函数的第二个参数，proj_id是可以根据自己的约定，随意设置
#define PROJ_ID 0x66
//定义共享内存的大小，最好是页(PAGE: 4096)的整数倍
#define SHM_SIZE 4096 

//定义命名管道，用来对共享内存进行访问控制。
#define FIFO_NAME "./fifo"

class Init
{
public:
    Init()
    {
        umask(0);
        //创建命名管道
        int n = mkfifo(FIFO_NAME, 0666);
        assert(n == 0);
        (void)n;
        Log("create fifo success",Notice) << "\n";
    }
    ~Init()
    {
        //删除命名管道
        unlink(FIFO_NAME);
        Log("remove fifo success",Notice) << "\n";
    }
};

// 定义读写方式
#define READ O_RDONLY
#define WRITE O_WRONLY

// 封装打开文件，pathname标识文件路径，flags标识读还是写
int OpenFIFO(std::string pathname, int flags)
{
    int fd = open(pathname.c_str(), flags);
    assert(fd >= 0);
    return fd;
}

//Wait函数表示一个进程等待
void Wait(int fd)
{
    Log("等待中....", Notice) << "\n";
    uint32_t temp = 0;
    //一次读四个字节的数据，没有数据就等待
    ssize_t s = read(fd, &temp, sizeof(uint32_t));
    assert(s == sizeof(uint32_t));
    (void)s;
}

//Signal函数表示唤醒一个进程
void Signal(int fd)
{
    uint32_t temp = 1;
    //写数据，此时等待的进程就可以运行了
    ssize_t s = write(fd, &temp, sizeof(uint32_t));
    assert(s == sizeof(uint32_t));
    (void)s;
    Log("唤醒中....", Notice) << "\n";
}

//关闭文件
void CloseFifo(int fd)
{
    close(fd);
}